package com.bstek.uflo.client.service.impl;

import com.bstek.uflo.client.model.BatchCompleteTaskInfo;
import com.bstek.uflo.client.model.CompleteTaskInfo;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.command.impl.jump.JumpNode;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.model.task.TaskAppointor;
import com.bstek.uflo.model.task.TaskParticipator;
import com.bstek.uflo.model.task.reminder.TaskReminder;
import com.bstek.uflo.query.TaskQuery;
import com.bstek.uflo.service.RestService;
import com.bstek.uflo.service.TaskOpinion;
import com.bstek.uflo.service.TaskService;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;

/**
 * @author Jacky.gao
 * @since 2013年9月22日
 */
public class TaskClientImpl implements TaskClient {
	private TaskService taskService;
	private RestService rest;

	public void setProgress(int progress,long taskId) {
		this.taskService.setProgress(progress,taskId);
	}

	public List<String> getAvaliableAppointAssigneeTaskNodes(long taskId) {
		return this.taskService.getAvaliableAppointAssigneeTaskNodes(taskId);
	}

	public List<String> getTaskNodeAssignees(long taskId, String taskNodeName) {
		return this.taskService.getTaskNodeAssignees(taskId, taskNodeName);
	}

	public void saveTaskAppointor(long taskId, String assignee, String taskNodeName) {
		this.taskService.saveTaskAppointor(taskId, assignee, taskNodeName);
	}

	public void saveTaskAppointor(long taskId, String[] assignees, String taskNodeName) {
		this.taskService.saveTaskAppointor(taskId, assignees, taskNodeName);
	}

	public Task addCountersign(long taskId, String username) {
		return this.taskService.addCountersign(taskId, username);
	}

	public void deleteCountersign(long taskId) {
		this.taskService.deleteCountersign(taskId);
	}

	public void rollback(long taskId, String targetNodeName) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			String uri = "/uflo/task/rollback";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.rollback(taskId, targetNodeName);
		}
	}

	public void rollback(long taskId, String targetNodeName, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			info.setVariables(variables);
			String uri = "/uflo/task/rollback";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.rollback(taskId, targetNodeName, variables);
		}
	}

	public void rollback(long taskId, String targetNodeName, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			info.setVariables(variables);
			String uri = "/uflo/task/rollback";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.rollback(taskId, targetNodeName, variables, opinion);
		}
	}

	public void rollback(Task task, String targetNodeName, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(task.getId());
			info.setTargetNodeName(targetNodeName);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			info.setVariables(variables);
			String uri = "/uflo/task/rollback";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.rollback(task, targetNodeName, variables, opinion);
		}
	}

	public List<JumpNode> getAvaliableForwardTaskNodes(long taskId) {
		return this.taskService.getAvaliableForwardTaskNodes(taskId);
	}

	public List<JumpNode> getAvaliableRollbackTaskNodes(long taskId) {
		return this.taskService.getAvaliableRollbackTaskNodes(taskId);
	}

	public void batchComplete(List<Long> taskIds, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			BatchCompleteTaskInfo info = new BatchCompleteTaskInfo();
			info.setTaskIds(taskIds);
			info.setVariables(variables);
			String uri = "/uflo/task/batch/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.batchComplete(taskIds, variables);
		}
	}

	public void batchStart(List<Long> taskIds) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			BatchCompleteTaskInfo info = new BatchCompleteTaskInfo();
			info.setTaskIds(taskIds);
			String uri = "/uflo/task/batch/start";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.batchStart(taskIds);
		}
	}

	public void batchStartAndComplete(List<Long> taskIds, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			BatchCompleteTaskInfo info = new BatchCompleteTaskInfo();
			info.setTaskIds(taskIds);
			info.setVariables(variables);
			String uri = "/uflo/task/batch/start/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.batchStartAndComplete(taskIds, variables);
		}
	}

	public void batchComplete(List<Long> taskIds, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			BatchCompleteTaskInfo info = new BatchCompleteTaskInfo();
			info.setTaskIds(taskIds);
			info.setVariables(variables);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/batch/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.batchComplete(taskIds, variables, opinion);
		}
	}

	public void batchStartAndComplete(List<Long> taskIds, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			BatchCompleteTaskInfo info = new BatchCompleteTaskInfo();
			info.setTaskIds(taskIds);
			info.setVariables(variables);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/batch/start/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.batchStartAndComplete(taskIds, variables, opinion);
		}
	}

	public void complete(long taskId, String flowName) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setFlowName(flowName);
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, flowName);
		}
	}

	public void complete(long taskId, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setVariables(variables);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, variables, opinion);
		}
	}

	public void complete(long taskId, String flowName, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setFlowName(flowName);
			info.setVariables(variables);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, flowName, variables, opinion);
		}
	}

	public void complete(long taskId, String flowName, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setFlowName(flowName);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, flowName, opinion);
		}
	}

	public void complete(long taskId, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, opinion);
		}
	}

	public void complete(long taskId, String flowName, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setFlowName(flowName);
			info.setVariables(variables);
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, flowName, variables);
		}
	}

	public void complete(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId);
		}
	}

	public void complete(long taskId, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setVariables(variables);
			String uri = "/uflo/task/complete";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.complete(taskId, variables);
		}
	}

	public void forward(long taskId, String targetNodeName) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			String uri = "/uflo/task/forward";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.forward(taskId, targetNodeName);
		}
	}

	public void forward(long taskId, String targetNodeName, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			info.setVariables(variables);
			String uri = "/uflo/task/forward";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.forward(taskId, targetNodeName, variables, opinion);
		}
	}

	public void forward(long taskId, String targetNodeName, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/forward";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.forward(taskId, targetNodeName, opinion);
		}
	}

	public void withdraw(long taskId, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setVariables(variables);
			String uri = "/uflo/task/withdraw";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.withdraw(taskId, variables);
		}
	}

	public void withdraw(long taskId, Map<String, Object> variables, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setVariables(variables);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/withdraw";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.withdraw(taskId, variables, opinion);
		}
	}

	public void withdraw(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			String uri = "/uflo/task/withdraw";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.withdraw(taskId);
		}
	}

	public void withdraw(long taskId, TaskOpinion opinion) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			if (opinion != null) {
				info.setOpinion(opinion.getOpinion());
			}
			String uri = "/uflo/task/withdraw";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.withdraw(taskId, opinion);
		}
	}

	public boolean canWithdraw(long taskId) {
		return this.taskService.canWithdraw(taskId);
	}

	public void forward(long taskId, String targetNodeName, Map<String, Object> variables) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			CompleteTaskInfo info = new CompleteTaskInfo();
			info.setTaskId(taskId);
			info.setTargetNodeName(targetNodeName);
			info.setVariables(variables);
			String uri = "/uflo/task/forward";
			this.rest.post(uri, info, null);
		} else {
			this.taskService.forward(taskId, targetNodeName, variables);
		}
	}

	public Task getTask(long taskId) {
		return this.taskService.getTask(taskId);
	}

	public void claim(long taskId, String username) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/task/claim/" + username + "/" + taskId + "";
			this.rest.post(uri, null, null);
		} else {
			this.taskService.claim(taskId, username);
		}
	}

	public void release(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/task/release/" + taskId + "";
			this.rest.post(uri, null, null);
		} else {
			this.taskService.release(taskId);
		}
	}

	public void start(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/task/start/" + taskId + "";
			this.rest.post(uri, null, null);
		} else {
			this.taskService.start(taskId);
		}
	}

	public void suspend(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/task/suspend/" + taskId + "";
			this.rest.post(uri, null, null);
		} else {
			this.taskService.suspend(taskId);
		}
	}

	public void resume(long taskId) {
		if (StringUtils.isNotEmpty(this.rest.getBaseUrl())) {
			String uri = "/uflo/task/resume/" + taskId + "";
			this.rest.post(uri, null, null);
		} else {
			this.taskService.resume(taskId);
		}
	}

	public String getUserData(Task task, String key) {
		return this.taskService.getUserData(task, key);
	}

	public String getUserData(long processId, String taskNodeName, String key) {
		return this.taskService.getUserData(processId, taskNodeName, key);
	}

	public List<TaskParticipator> getTaskParticipators(long taskId) {
		return this.taskService.getTaskParticipators(taskId);
	}

	public List<TaskAppointor> getTaskAppointors(String taskNodeName, long processInstanceId) {
		return this.taskService.getTaskAppointors(taskNodeName, processInstanceId);
	}

	public TaskQuery createTaskQuery() {
		return this.taskService.createTaskQuery();
	}

	public List<TaskReminder> getTaskReminders(long taskId) {
		return this.taskService.getTaskReminders(taskId);
	}

	public void deleteTaskReminder(long taskReminderId) {
		this.taskService.deleteTaskReminder(taskReminderId);
	}

	public List<TaskReminder> getAllTaskReminders() {
		return this.taskService.getAllTaskReminders();
	}

	public void changeTaskAssignee(long taskId, String username) {
		this.taskService.changeTaskAssignee(taskId, username);
	}

	public RestService getRest() {
		return this.rest;
	}

	public void setRest(RestService rest) {
		this.rest = rest;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}
}